﻿Option Strict Off
Option Explicit Off

Imports Brainworklite.BussinesLogic
Imports Brainworklite.Entity
Imports Brainworklite.Entity.Attributes
Imports System.Web.UI.WebControls
Imports System.Reflection
Imports System.Web.UI
Imports Brainworklite.Core.ReflectionHelper
Imports System.ComponentModel
Imports System.Web

Public Class Loaders(Of T)

    Private ReadOnly Property Page() As Page
        Get
            Dim h = HttpContext.Current.Handler
            Return DirectCast(h, Page)
        End Get
    End Property

    'int startIndex, int pageSize, string sortBy
    Private _size As Integer = 0
    Public Property Size() As Integer
        Get
            Return _size
        End Get
        Set(ByVal value As Integer)
            _size = value
        End Set
    End Property
    Private lastSort As String = ""
    Private lastSortDirection As String = " ASC "


    Public Sub New()
        Dim key = Page.GetType().Name & ".ViewState"
        If Page.IsPostBack = False Then
            Brainworklite.Core.CacheMannager.SetInCache(Of Loaders(Of T), Object)(key, New Dictionary(Of String, Object), 20)
        End If
    End Sub
    Private ReadOnly Property _ViewState() As Dictionary(Of String, Object)
        Get
            Dim key = Page.GetType().Name & ".ViewState"

            Dim vale = Brainworklite.Core.CacheMannager.getFromCache(Of Loaders(Of T), Object)(key)
            If vale Is Nothing Then
                Brainworklite.Core.CacheMannager.SetInCache(Of Loaders(Of T), Object)(key, New Dictionary(Of String, Object), 20)
                vale = Brainworklite.Core.CacheMannager.getFromCache(Of Loaders(Of T), Object)(key)
            End If
            Return vale
        End Get
    End Property

    Private Property ViewState(ByVal keypart As String) As Object
        Get
            Dim key = Page.GetType().Name & "ViewState." & keypart
            If _ViewState.ContainsKey(key) Then
                Return _ViewState(key)
            End If
            Return Nothing
        End Get

        Set(ByVal value As Object)
            Dim key = Page.GetType().Name & "ViewState." & keypart
            If _ViewState.ContainsKey(key) Then
                _ViewState(key) = value
            Else
                _ViewState.Add(key, value)
            End If

        End Set
    End Property

    Private Property OrderBy() As String
        Get
            If ViewState("_OrderBy") Is Nothing Then
                ViewState("_OrderBy") = GetObject().getPrimaryKeyProperty().FieldMappingAtt.DbFieldMapp
            End If
            Return CStr(ViewState("_OrderBy"))
        End Get
        Set(ByVal value As String)
            'value = getObject().PropertiesAttributes().Where(Function(x) x.Value.LabelAtt.Text.Equals(value)).FirstOrDefault().Value.FieldMappingAtt.DbFieldMapp
            ViewState("_OrderBy") = value
        End Set
    End Property
    Private Property SortDirection() As String
        Get
            If ViewState("_SortDirection") Is Nothing Then
                ViewState("_SortDirection") = " ASC "
            End If
            Return CStr(ViewState("_SortDirection"))
        End Get
        Set(ByVal value As String)
            ViewState("_SortDirection") = value
        End Set
    End Property

    Private Function getSortDirection(ByVal expression As String) As String
        If Page.IsPostBack AndAlso sortDirections.ContainsKey(expression) Then
            If sortDirections(expression) = " ASC " Then
                sortDirections(expression) = " DESC "
            Else
                sortDirections(expression) = " ASC "
            End If
        Else
            sortDirections.Add(expression, " ASC ")
        End If
        Return sortDirections(expression)
    End Function
    Private ReadOnly Property sortDirections() As Dictionary(Of String, String)
        Get
            If ViewState("_sortDirections") Is Nothing Then
                ViewState("_sortDirections") = New Dictionary(Of String, String)
            End If
            Return DirectCast(ViewState("_sortDirections"), Dictionary(Of String, String))
        End Get
    End Property


    <DataObjectMethod(DataObjectMethodType.Select)> _
    Public Function DataSourceSearch(ByVal sortBy As String, ByVal pageSize As Integer, ByVal startIndex As Integer) As DataTable
        Dim loader As New BussinesLogicGeneric(Of T)
        If startIndex > 0 Then
            startIndex += 1
        End If

        If sortBy IsNot Nothing AndAlso Not String.IsNullOrEmpty(sortBy) Then
            sortBy = sortBy.Trim()
            If sortBy.EndsWith("DESC") Then
                sortBy = sortBy.Remove(sortBy.Length - 4).Trim()
            ElseIf sortBy.EndsWith("ASC") Then
                sortBy = sortBy.Remove(sortBy.Length - 3).Trim()
            End If
            Dim lv = EntityBaseInstance.PropertiesAttributes().Where(Function(x) x.Value.LabelAtt.Text.Equals(sortBy))
            If lv.Any() Then
                sortBy = lv.FirstOrDefault().Value.FieldMappingAtt.DbFieldMapp
            Else
                sortBy = Nothing
                Dim lv2 = EntityBaseInstance.PropertiesAttributes().Where(Function(x) x.Value.ForeingClassMapping IsNot Nothing OrElse x.Value.ForeingKeyTableMapp IsNot Nothing OrElse x.Value.MultiInputForeingClassMapping IsNot Nothing)
                If lv2.Any() Then
                    Dim pa = lv2.FirstOrDefault()
                    If pa.Value.MultiInputForeingClassMapping IsNot Nothing Then
                        Dim inst1 = Core.ReflectionHelper.GetEntityClassInstance(pa.Value.MultiInputForeingClassMapping.MappingClassName)
                        Dim ent1 = DirectCast(inst1, EntityBase)

                    End If
                End If

            End If
        Else
            sortBy = EntityBaseInstance.getPrimaryKeyProperty().FieldMappingAtt.DbFieldMapp()
        End If
        sortBy = sortBy + getSortDirection(sortBy)

        Dim ds = loader.getListDataSource(startIndex, startIndex + pageSize, sortBy, System.Web.HttpContext.Current.Session(GetType(T).FullName & ".grid"))
        _size = ds.Tables(1).Rows(0)(0)
        Return ds.Tables(0)
    End Function

    Public Function DataSourceSearchgetCount() As Integer
        Return _size
    End Function


    Private _getBussinesLogic As BussinesLogicGeneric(Of T)
    Private ReadOnly Property getBL() As BussinesLogicGeneric(Of T)
        Get
            If _getBussinesLogic Is Nothing Then
                _getBussinesLogic = New BussinesLogicGeneric(Of T)()
            End If
            Return _getBussinesLogic
        End Get

    End Property

    Private Function CreateInstance() As T
        Return Activator.CreateInstance(Of T)()
    End Function

    Private Function CreateInstanceOfEntityBase() As Entity.EntityBase
        Return CType(CObj(CreateInstance()), EntityBase)
    End Function

    Private _CurrentInstace As EntityBase
    Private ReadOnly Property EntityBaseInstance() As Entity.EntityBase
        Get
            If _CurrentInstace Is Nothing Then
                _CurrentInstace = CreateInstanceOfEntityBase()
            End If
            Return _CurrentInstace
        End Get
    End Property


    Private ReadOnly Property ClassAttributes() As Attributes.SelfMappClassAttribute
        Get
            Return EntityBaseInstance.ClassAttribute
        End Get
    End Property

    Private ReadOnly Property PropertiesAtt() As Dictionary(Of String, Attributes.PropertiesAttributes)
        Get
            Return EntityBaseInstance.PropertiesAttributes
        End Get
    End Property



    Public Sub FullFill(ByVal ctl As System.Web.UI.WebControls.DropDownList)


        FullFill(ctl, EntityBase.DataValueFieldName, EntityBase.DataTextFieldName)

    End Sub

    Public Sub FullFillWithEmpty(ByVal ctl As System.Web.UI.WebControls.DropDownList, _
                                 ByVal qe As BussinesLogic.WhereQueryExpression, _
                                 Optional ByVal Emptymessage As String = Nothing)
        Dim DataSource As New List(Of Object)

        If Not String.IsNullOrEmpty(Emptymessage) Then
            DataSource.Add(New With {.DataValueField = Nothing, .DataTextField = Emptymessage})
        Else

            DataSource.Add(New With {.DataValueField = Nothing, .DataTextField = "------Select-----"})
        End If


        DataSource.AddRange(getBL().getDataTextValueList(qe))
        ctl.DataSource = DataSource
        ctl.DataValueField = EntityBase.DataValueFieldName
        ctl.DataTextField = EntityBase.DataTextFieldName
        ctl.DataBind()
    End Sub

    Public Sub FullFillDistinctWithEmpty(ByVal ctl As System.Web.UI.WebControls.DropDownList, _
                              ByVal qe As BussinesLogic.WhereQueryExpression, _
                              Optional ByVal Emptymessage As String = Nothing)
        Dim DataSource As New List(Of Object)

        If Not String.IsNullOrEmpty(Emptymessage) Then
            DataSource.Add(New With {.DataValueField = Nothing, .DataTextField = Emptymessage})
        Else

            DataSource.Add(New With {.DataValueField = Nothing, .DataTextField = "------Select-----"})
        End If

        Dim ln = (From c In getBL().getDataTextValueList(qe) Select New With {Key c.DataValueField, c.DataTextField} Distinct).OrderBy(Function(x) x.DataTextField).ToList().Cast(Of Object)()



        DataSource.AddRange(ln)
        ctl.DataSource = DataSource
        ctl.DataValueField = EntityBase.DataValueFieldName
        ctl.DataTextField = EntityBase.DataTextFieldName
        ctl.DataBind()
    End Sub

    Public Sub FullFill(ByVal ctl As System.Web.UI.WebControls.DropDownList, ByVal qe As BussinesLogic.WhereQueryExpression)
        Dim DataSource = getBL().getList(qe)
        ctl.DataSource = DataSource
        ctl.DataValueField = EntityBase.DataValueFieldName
        ctl.DataTextField = EntityBase.DataTextFieldName
        ctl.DataBind()
    End Sub

    Public Sub FullFill(ByVal ctl As System.Web.UI.WebControls.DropDownList, ByVal DataValueFieldName As String, ByVal DataTextFieldName As String)

        FullFill(ctl, getBL().getEntityBaseList(), DataValueFieldName, DataTextFieldName)
    End Sub

    Public Sub FullFill(ByVal ctl As System.Web.UI.WebControls.DropDownList, ByVal DataSource As IEnumerable(Of T), ByVal DataValueFieldName As String, ByVal DataTextFieldName As String)
        ctl.DataSource = DataSource
        ctl.DataValueField = DataValueFieldName
        ctl.DataTextField = DataTextFieldName
        ctl.DataBind()
    End Sub

    Public Sub FullFill(ByVal ctl As System.Web.UI.WebControls.DropDownList, ByVal DataSource As IEnumerable(Of EntityBase), ByVal DataValueFieldName As String, ByVal DataTextFieldName As String)
        ctl.DataSource = DataSource
        ctl.DataValueField = DataValueFieldName
        ctl.DataTextField = DataTextFieldName
        ctl.DataBind()
    End Sub

    Public Sub FullFill(ByVal ctl As System.Web.UI.WebControls.DropDownList, ByVal DataSource As IEnumerable(Of T))
        ctl.DataSource = DataSource
        ctl.DataValueField = EntityBase.DataValueFieldName
        ctl.DataTextField = EntityBase.DataTextFieldName

        ctl.DataBind()
    End Sub

    Public Sub FullFill(ByVal ctl As System.Web.UI.WebControls.GridView, ByVal columntextSplit As String)
        FullFill(ctl, columntextSplit.Split(","))
    End Sub



    Public Sub FullFill(ByVal ctl As System.Web.UI.WebControls.GridView, ByVal ParamArray ListOfFields() As String)



        Dim dt = getBL().getDataTable()
        If ListOfFields IsNot Nothing AndAlso ListOfFields.Count() > 0 Then

            Dim dicOrder As New Dictionary(Of String, Integer)
            ' Dim index As Integer = 0
            Dim obEnt = EntityBaseInstance.PropertiesAttributes()

            Dim listOfFieldsUpper = ListOfFields.Select(Function(x) x.ToUpper()).ToArray()

            For Each dc As DataColumn In dt.Clone().Columns

                Dim orignColumnsName = dc.ColumnName.ToUpper()

                If listOfFieldsUpper.Where(Function(x) x.Equals(orignColumnsName, StringComparison.InvariantCultureIgnoreCase)).Any() Then
                    Dim propName = obEnt(dc.ColumnName).LabelAtt.Text
                    dt.Columns(dc.ColumnName).ColumnName = propName
                    dicOrder.Add(propName, Array.IndexOf(listOfFieldsUpper, orignColumnsName))
                    'index += 1
                Else
                    dt.Columns.Remove(dc.ColumnName)
                End If
            Next



            For Each item In dicOrder
                dt.Columns(item.Key).SetOrdinal(item.Value)
            Next



        End If

        ctl.DataSource = dt
        ctl.DataBind()
        ctl.AutoGenerateColumns = True
        'Dim cc = ctl.Columns.Count
        'Dim lstcol = ctl.Columns

        ctl.AutoGenerateDeleteButton = True
        ctl.AutoGenerateEditButton = True
        ctl.AutoGenerateSelectButton = True

    End Sub







End Class


'A customized class for displaying the Template Column
Public Class GridViewTemplate
    Implements ITemplate
    'A variable to hold the type of ListItemType.
    Private _templateType As ListItemType

    'A variable to hold the column name.
    Private _columnName As String

    'Constructor where we define the template type and column name.
    Public Sub New(ByVal type As ListItemType, ByVal colname As String)
        'Stores the template type.
        _templateType = type

        'Stores the column name.
        _columnName = colname
    End Sub

    Private Sub ITemplate_InstantiateIn(ByVal container As System.Web.UI.Control) Implements ITemplate.InstantiateIn
        Select Case _templateType
            Case ListItemType.Header
                'Creates a new label control and add it to the container.
                Dim lbl As New Label()
                'Allocates the new label object.
                lbl.Text = _columnName
                'Assigns the name of the column in the lable.
                container.Controls.Add(lbl)
                'Adds the newly created label control to the container.
                Exit Select

            Case ListItemType.Item
                'Creates a new text box control and add it to the container.
                Dim tb1 As New TextBox()
                'Allocates the new text box object.
                AddHandler tb1.DataBinding, AddressOf tb1_DataBinding
                ' tb1.DataBinding += New EventHandler(AddressOf tb1_DataBinding)
                'Attaches the data binding event.
                tb1.Columns = 4
                'Creates a column with size 4.
                container.Controls.Add(tb1)
                'Adds the newly created textbox to the container.
                Exit Select

            Case ListItemType.EditItem
                'As, I am not using any EditItem, I didnot added any code here.
                Exit Select

            Case ListItemType.Footer
                Dim chkColumn As New CheckBox()
                chkColumn.ID = "Chk" & _columnName
                container.Controls.Add(chkColumn)
                Exit Select
        End Select
    End Sub

    ''' <summary>
    ''' This is the event, which will be raised when the binding happens.
    ''' </summary>
    ''' <param name="sender"></param>
    ''' <param name="e"></param>
    Private Sub tb1_DataBinding(ByVal sender As Object, ByVal e As EventArgs)
        Dim txtdata As TextBox = DirectCast(sender, TextBox)
        Dim container As GridViewRow = DirectCast(txtdata.NamingContainer, GridViewRow)
        Dim dataValue As Object = DataBinder.Eval(container.DataItem, _columnName)
        If dataValue IsNot DBNull.Value Then
            txtdata.Text = dataValue.ToString()
        End If
    End Sub
End Class

